return do_domctl(xc_handle, &domctl);
}
+int xc_domain_disable_migrate(int xc_handle, uint32_t domid)
+{
+ DECLARE_DOMCTL;
+ domctl.cmd = XEN_DOMCTL_disable_migrate;
+ domctl.domain = (domid_t)domid;
+ domctl.u.disable_migrate.disable = 1;
+ return do_domctl(xc_handle, &domctl);
+}
+
int xc_domain_memory_increase_reservation(int xc_handle,
uint32_t domid,
unsigned long nr_extents,
int xc_domain_set_tsc_native(int xc_handle, uint32_t domid, int is_native);
+int xc_domain_disable_migrate(int xc_handle, uint32_t domid);
+
int xc_domain_memory_increase_reservation(int xc_handle,
uint32_t domid,
unsigned long nr_extents,
return zero;
}
+static PyObject *pyxc_domain_disable_migrate(XcObject *self, PyObject *args)
+{
+ uint32_t dom;
+
+ if (!PyArg_ParseTuple(args, "i", &dom))
+ return NULL;
+
+ if (xc_domain_disable_migrate(self->xc_handle, dom) != 0)
+ return pyxc_error_to_exception();
+
+ Py_INCREF(zero);
+ return zero;
+}
+
static PyObject *pyxc_domain_send_trigger(XcObject *self,
PyObject *args,
PyObject *kwds)
" is_native [int]: 1=native, 0=emulate.\n"
"Returns: [int] 0 on success; -1 on error.\n" },
+ { "domain_disable_migrate",
+ (PyCFunction)pyxc_domain_disable_migrate,
+ METH_VARARGS, "\n"
+ "Marks domain as non-migratable AND non-restoreable\n"
+ " dom [int]: Domain whose TSC mode is being set.\n"
+ "Returns: [int] 0 on success; -1 on error.\n" },
+
{ "domain_send_trigger",
(PyCFunction)pyxc_domain_send_trigger,
METH_VARARGS | METH_KEYWORDS, "\n"
else:
dominfo = xd.restore_(vmconfig)
+ image_cfg = dominfo.info.get('image', {})
+ is_hvm = dominfo.info.is_hvm()
+
+ if is_hvm:
+ nomigrate = dominfo.info['platform'].get('nomigrate', 0)
+ else:
+ nomigrate = dominfo.info['platform'].get('nomigrate')
+ if nomigrate is None:
+ nomigrate = 0
+ if int(nomigrate) != 0:
+ dominfo.destroy()
+ raise XendError("cannot restore non-migratable domain")
+
# repin domain vcpus if a target node number was specified
# this is done prior to memory allocation to aide in memory
# distribution for NUMA systems.
assert console_port
# if hvm, pass mem size to calculate the store_mfn
- image_cfg = dominfo.info.get('image', {})
- is_hvm = dominfo.info.is_hvm()
if is_hvm:
apic = int(dominfo.info['platform'].get('apic', 0))
pae = int(dominfo.info['platform'].get('pae', 0))
'localtime': int,
'monitor': int,
'nographic': int,
+ 'nomigrate': int,
'pae' : int,
'rtc_timeoffset': int,
'serial': str,
if 'tsc_native' not in self['platform']:
self['platform']['tsc_native'] = 0
+ if 'nomigrate' not in self['platform']:
+ self['platform']['nomigrate'] = 0
+
if self.is_hvm():
if 'timer_mode' not in self['platform']:
self['platform']['timer_mode'] = 1
if arch.type == "x86" and hvm and viridian is not None:
xc.hvm_set_param(self.domid, HVM_PARAM_VIRIDIAN, long(viridian))
+ # If nomigrate is set, disable migration
+ nomigrate = self.info["platform"].get("nomigrate")
+ if arch.type == "x86" and nomigrate is not None and long(nomigrate) != 0:
+ xc.domain_disable_migrate(self.domid)
+
# Optionally enable virtual HPET
hpet = self.info["platform"].get("hpet")
if hvm and hpet is not None:
fn=set_int, default=0,
use="""TSC mode (0=emulate TSC, 1=native TSC).""")
+gopts.var('nomigrate', val='NOMIGRATE',
+ fn=set_int, default=0,
+ use="""migratability (0=migration enabled, 1=migration disabled).""")
+
gopts.var('vpt_align', val='VPT_ALIGN',
fn=set_int, default=1,
use="Enable aligning all periodic vpt to reduce timer interrupts.")
if vals.tsc_native is not None:
config_image.append(['tsc_native', vals.tsc_native])
+ if vals.nomigrate is not None:
+ config_image.append(['nomigrate', vals.nomigrate])
+
return config_image
def configure_disks(config_devs, vals):
config.append([n, v])
map(add_conf, ['name', 'memory', 'maxmem', 'shadow_memory',
- 'restart', 'on_poweroff', 'tsc_native',
+ 'restart', 'on_poweroff', 'tsc_native', 'nomigrate',
'on_reboot', 'on_crash', 'vcpus', 'vcpu_avail', 'features',
'on_xend_start', 'on_xend_stop', 'target', 'cpuid',
'cpuid_check', 'machine_address_size', 'suppress_spurious_page_faults'])
'xen_platform_pci',
'tsc_native'
'description',
+ 'nomigrate'
]
platform_configs = []
spin_lock_init(&d->arch.vtsc_lock);
+ if ( d->domain_id == 0 )
+ d->disable_migrate = 1;
+
return 0;
fail:
}
break;
+ case XEN_DOMCTL_disable_migrate:
+ {
+ struct domain *d;
+
+ ret = -ESRCH;
+ d = rcu_lock_domain_by_id(domctl->domain);
+ if ( d == NULL )
+ break;
+
+ domain_pause(d);
+ d->arch.disable_migrate = domctl->u.disable_migrate.disable;
+ domain_unpause(d);
+
+ rcu_unlock_domain(d);
+ ret = 0;
+ }
+ break;
+
case XEN_DOMCTL_suppress_spurious_page_faults:
{
struct domain *d;
spinlock_t vtsc_lock;
uint64_t vtsc_kerncount; /* for hvm, counts all vtsc */
uint64_t vtsc_usercount; /* not used for hvm */
+
+ /* mark domain as non-migratable and non-restoreable */
+ bool_t disable_migrate;
} __cacheline_aligned;
#define has_arch_pdevs(d) (!list_empty(&(d)->arch.pdev_list))
} xen_domctl_hvmcontext_partial_t;
DEFINE_XEN_GUEST_HANDLE(xen_domctl_hvmcontext_partial_t);
+#define XEN_DOMCTL_disable_migrate 58
+typedef struct xen_domctl_disable_migrate {
+ uint32_t disable; /* IN: 1: disable migration and restore */
+} xen_domctl_disable_migrate_t;
+
+
#define XEN_DOMCTL_gdbsx_guestmemio 1000 /* guest mem io */
struct xen_domctl_gdbsx_memio {
uint64_aligned_t pgd3val;/* optional: init_mm.pgd[3] value */
struct xen_domctl_arch_setup arch_setup;
struct xen_domctl_settimeoffset settimeoffset;
struct xen_domctl_set_tsc_native set_tsc_native;
+ struct xen_domctl_disable_migrate disable_migrate;
struct xen_domctl_real_mode_area real_mode_area;
struct xen_domctl_hvmcontext hvmcontext;
struct xen_domctl_hvmcontext_partial hvmcontext_partial;